/**
 *
 * \file
 * CGI and SSI functions.
 *
 */

/*
 *
 * Copyright (c) 2010, Jesper Hansen
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 *
 *      * Redistributions of source code must retain the above copyright notice, this
 *       list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright notice,
 *       this list of conditions and the following disclaimer in the documentation
 *       and/or other materials provided with the distribution.
 *     * Neither the name of the copyright holders nor the names of any contributors
 *       may be used to endorse or promote products derived from this software
 *       without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 *
 */



#include "inc/hw_types.h"
#include "utils/lwiplib.h"
#include "utils/uartstdio.h"
#include "utils/ustdlib.h"
#include "httpserver_raw/httpd.h"


#include <stdint.h>
#include <string.h>

#include "isendir.h"

#include "timeout.h"

#include "cgifuncs.h"


//*****************************************************************************
//!
//! This array holds all the strings that are to be recognized as SSI tag
//! names by the HTTPD server.  The server will call SSIHandler to request a
//! replacement string whenever the pattern <!--#tagname--> (where tagname
//! appears in the following array) is found in ".ssi", ".shtml" or ".shtm"
//! files that it serves.
//!
//*****************************************************************************
static const char *g_pcConfigSSITags[] =
{
     "fwver",		// 0
     "fwtime",		// 1
     "ip",			// 2
     "mac",			// 3
     "netvars",		// 4
     "FormVars"		// 5
};

//*****************************************************************************
//!
//! The number of individual SSI tags that the HTTPD server can expect to
//! find in our configuration pages.
//!
//*****************************************************************************
#define NUM_CONFIG_SSI_TAGS     (sizeof(g_pcConfigSSITags) / sizeof (g_pcConfigSSITags[0]))

//*****************************************************************************
//!
//! Prototype for the main handler used to process server-side-includes for the
//! application's web-based configuration screens.
//!
//*****************************************************************************
static int SSIHandler(int iIndex, char *pcInsert, int iInsertLen);







//*****************************************************************************
//!
//! Prototypes for the various CGI handler functions.
//!
//*****************************************************************************
static char *NetworkCGIHandler(int iIndex, int iNumParams, char *pcParam[],
                               char *pcValue[]);



 //*****************************************************************************
 //!
 //! This array is passed to the HTTPD server to inform it of special URIs
 //! that are treated as common gateway interface (CGI) scripts.  Each URI name
 //! is defined along with a pointer to the function which is to be called to
 //! process it.
 //!
 //*****************************************************************************
 static const tCGI g_psConfigCGIURIs[] =
 {
     { "/network.cgi", NetworkCGIHandler }		// 0
     //{ "/settxt.cgi", SetTextCGIHandler }		// 1
 };

 //*****************************************************************************
 //!
 //! The number of individual CGI URIs that are configured for this system.
 //!
 //*****************************************************************************
 #define NUM_CONFIG_CGI_URIS     (sizeof(g_psConfigCGIURIs) / sizeof(g_psConfigCGIURIs[0]))


//*****************************************************************************
//
//! The file sent back to the browser in cases where a parameter error is
//! detected by one of the CGI handlers.  This should only happen if someone
//! tries to access the CGI directly via the broswer command line and doesn't
//! enter all the required parameters alongside the URI.
//
//*****************************************************************************
#define PARAM_ERROR_RESPONSE    "/perror.htm"

/*
#define JAVASCRIPT_HEADER                                                     \
    "<script type='text/javascript' language='JavaScript'><!--\n"
#define JAVASCRIPT_FOOTER                                                     \
    "//--></script>\n"
*/

 //*****************************************************************************
 //!
 //! This CGI handler is called whenever the web browser requests network.cgi.
 //!
 //*****************************************************************************
 static char *
 NetworkCGIHandler(int iIndex, int iNumParams, char *pcParam[], char *pcValue[])
 {
     tBoolean bParamError;
     long  lParam;
     char pcDecodedString[24];

     printf("NetworkCGIHandler\n");

     //
     // Clear error marker
     //
     bParamError = false;

     nw_settings.ns_usedhcp = GetCGIParamBool("dhcpenabled", pcParam, pcValue, iNumParams, &bParamError);

     if (bParamError)
    	 printf("dhcp param failed\n");
     else
     {
    	 printf("dhcpenabled=%d\n",nw_settings.ns_usedhcp);

		 if (!nw_settings.ns_usedhcp)	// using static address
		 {
			 if ( (lParam = FindCGIParameter("ipaddress", pcParam, iNumParams)) == -1)
				 return(PARAM_ERROR_RESPONSE);
			 DecodeFormString(pcValue[lParam], pcDecodedString, 24);
			 nw_settings.ns_ipaddr = ntohl(inet_addr(pcDecodedString));

			 if ( (lParam = FindCGIParameter("netmask", pcParam, iNumParams)) == -1)
				 return(PARAM_ERROR_RESPONSE);
			 DecodeFormString(pcValue[lParam], pcDecodedString, 24);
			 nw_settings.ns_netmask = ntohl(inet_addr(pcDecodedString));

			 if ( (lParam = FindCGIParameter("gateway", pcParam, iNumParams)) == -1)
				 return(PARAM_ERROR_RESPONSE);
			 DecodeFormString(pcValue[lParam], pcDecodedString, 24);
			 nw_settings.ns_gwaddr = ntohl(inet_addr(pcDecodedString));
		 }

	     //
	     // get new Beacon setting
	     //
		 nw_settings.ns_beacon_bpm = GetCGIParam("beacon", pcParam, pcValue, iNumParams, &bParamError);
		 if (bParamError)
			 nw_settings.ns_beacon_bpm = 1;	// set default in case of error

		 //
		 // set flag to cause a network reconfiguration
		 //
		 g_flags |= FLAG_NETCONFIG;
     }

     //
     // Return the response page.
     //
     return("/network.html");
 }







 //*****************************************************************************
 //!
 //! This function is called by the HTTP server whenever it encounters an SSI
 //! tag in a web page.  The iIndex parameter provides the index of the tag in
 //! the g_pcConfigSSITags array. This function writes the substitution text
 //! into the pcInsert array, writing no more than iInsertLen characters.
 //!
 //*****************************************************************************
 static int SSIHandler(int iIndex, char *pcInsert, int iInsertLen)
 {
	 char ip[16];
	 char nm[16];
	 char gw[16];
	 char mac[20];

     //
     // Which SSI tag have we been passed?
     //
     switch(iIndex)
     {
         case 0:	// fwversion
             usnprintf(pcInsert, iInsertLen, __FWVERSION__);
             break;

         case 1:	// fwtime
             usnprintf(pcInsert, iInsertLen, __FWCOMPILETIME__);
             break;

         case 2:	// ip
      		 usnprintf(pcInsert, iInsertLen, ip2string(ip, lwIPLocalIPAddrGet()));
             break;

         case 3:	//mac
             usnprintf(pcInsert, iInsertLen, mac2string(mac,"%02x-%02x-%02x-%02x-%02x-%02x"));
             break;

         case 4: // netvars
             usnprintf(pcInsert, iInsertLen,
                       "\nde=%d;\nip='%s';\nnm='%s';\ngw='%s';\nbc=%d;\n",
                       //JAVASCRIPT_HEADER,
                       (lwIPIPModeGet() == IPADDR_USE_DHCP) ? 1 : 0,
                       ip2string(ip, lwIPLocalIPAddrGet() ),
                       ip2string(nm, lwIPLocalNetMaskGet() ),
                       ip2string(gw, lwIPLocalGWAddrGet() ),
                       nw_settings.ns_beacon_bpm/*,
                       JAVASCRIPT_FOOTER*/);
        	 break;

         /*case 5: // FormVars
             usnprintf(pcInsert, iInsertLen,
                       "%sde=%d;\nip=%s;\nnm=%s;\ngw=%s;\n%s",
                       JAVASCRIPT_HEADER,
                       1,
                       "192.168.14.15",
                       "255.254.254.0",
                       "192.168.1.1",
                       JAVASCRIPT_FOOTER);
             break;*/

         default:
             usnprintf(pcInsert, iInsertLen, "??");
             break;
     }

     //
     // Tell the server how many characters our insert string contains.
     //
     return(strlen(pcInsert));
 }








 //*****************************************************************************
 //!
 //! Initialize the CGI and SSI functionality by setting up pointers to
 //! the arrays of tags and handlers.
 //!
 //*****************************************************************************
void cgissi_init(void)
{
	//
	// Pass our tag information to the HTTP server.
	//
	http_set_ssi_handler(SSIHandler, g_pcConfigSSITags, NUM_CONFIG_SSI_TAGS);

	//
	// Pass our CGI handlers to the HTTP server.
	//
	http_set_cgi_handlers(g_psConfigCGIURIs, NUM_CONFIG_CGI_URIS);
}



